export default {
    /**
     * 深度拷贝
     *
     * @param {Object} object - 被拷贝对象
     * @return {Object} copy - 新目标对象
     */
    deepCopy(object) {
        let copyObj;
        if (null == object || "object" != typeof object) {
            return object;
        }
        if (object instanceof Date) {
            copyObj = new Date();
            copyObj.setTime(object.getTime());
            return copyObj;
        }

        if (object instanceof Array) {
            copyObj = [];
            for (let i = 0, len = object.length; i < len; i++) {
                copyObj[i] = this.deepCopy(object[i]);
            }
            return copyObj;
        }

        if (object instanceof Object) {
            copyObj = {};
            for (let attr in object) {
                copyObj[attr] = this.deepCopy(object[attr]);
            }
            return copyObj;
        }
    },
    //数据转换
    jsonParse(res) {
        let data;
        try {
            data = JSON.parse(res);
        } catch (err) {
            let dataStr = res.replace(/:"{/g, ":{");
            dataStr = dataStr.replace(/}",/g, "},");
            dataStr = dataStr.replace(/\\/g, "");
            data = JSON.parse(dataStr);
        }
        return data;
    },

    // 函数防抖
    debounce(fn, delay, scope) {
        let timer = null;
        // 返回函数对debounce作用域形成闭包
        return function () {
            // setTimeout()中用到函数环境总是window,故需要当前环境的副本；
            let context = scope || this,
                args = arguments;
            // 如果事件被触发，清除timer并重新开始计时
            clearTimeout(timer);
            timer = setTimeout(function () {
                fn.apply(context, args);
            }, delay);
        };
    },

    //节流
    throttle(fn, delay = 1000) {
        let timer = null;
        let firstTime = true;
        return function (...args) {
            if (firstTime) {
                // 第一次加载
                fn.apply(this, args);
                return (firstTime = false);
            }
            if (timer) {
                // 定时器正在执行中，跳过
                return;
            }
            timer = setTimeout(() => {
                clearTimeout(timer);
                timer = null;
                fn.apply(this, args);
            }, delay);
        };
    },

    //判断设备
    getDeviceOs() {
        let ua = navigator.userAgent,
            isAndroid = /(?:Android)/.test(ua),
            isFireFox = /(?:Firefox)/.test(ua),
            isTablet =
            /(?:iPad|PlayBook)/.test(ua) ||
            (isAndroid && !/(?:Mobile)/.test(ua)) ||
            (isFireFox && /(?:Tablet)/.test(ua)),
            isPhone = /(?:iPhone)/.test(ua) && !isTablet;

        return {
            isTablet: isTablet,
            isPhone: isPhone,
            isAndroid: isAndroid,
        };
    },

    //是否横竖屏
    isOrientation() {
        if (window.orientation == 180 || window.orientation == 0) {
            // 竖屏
            return true;
        } else if (window.orientation == 90 || window.orientation == -90) {
            // 横屏
            return false;
        }
    },

    /**
     * @description: 16进制转二进制
     * @param {*} 16进制
     * @return {*}
     */
    hextoBin(hex) {
        let str = parseInt(hex, 16).toString(2);
        while (str.length < 8) {
            str = "0" + str;
        }
        return str;
    },

    /**
     * @description: 二进制转16进制
     * @param {*} 二进制
     * @return {*}
     */
    bintoHex(bin) {
        let str = parseInt(bin, 2).toString(16);
        str = str.length == 1 ? "0" + str : str;
        return str;
    },

    /**
     * @description: 校验数据 并拼接16进制
     * @param {Number} s 要改变数据的下标
     * @param {String} newData 要改变数据的新值
     * @param {String} oldData 要改变数据
     * @return {*}
     */
    checkData(s, newData, oldData) {
        let bin1 = null;
        let binArr = oldData.split("");
        binArr[4] = "0";
        binArr[0] = binArr[0] + binArr[1];
        binArr[s] = newData;
        binArr.splice(1, 1);
        bin1 = binArr.join("");
        let bin2 = 0b0;
        let checkCode = (
            parseInt(parseInt(bin1, 2), 10) + parseInt(parseInt(bin2, 2), 10)
        ).toString(16);
        checkCode = checkCode.length == 1 ? "0" + checkCode : checkCode;
        bin1 =
            parseInt(parseInt(bin1, 2), 10).toString(16).length == 1 ?
            "0" + parseInt(parseInt(bin1, 2), 10).toString(16) :
            parseInt(parseInt(bin1, 2), 10).toString(16);
        return "AA" + bin1 + "00" + checkCode;
    },
    /**
     * 获取校验和
     * @param str 16进制字符串
     * 
     * @return 10进制检验和
     */
    getCheckSum(str) {
        let len = str.length;
        let num = 0;
        for (let i = 0; i < len; i += 2) {
            let s = `0x${str.slice(i, i+2)}`;
            num += parseInt(s, 16);
        }

        return (num % 256).toString(16);
    },
    getChecksumWithStr(str) {
        let sumNum = 0;
        // 求十进制的和
        for (let i = 0; i < str.length; i += 2) {
            let s = `0x${str[i]}${str[i + 1]}`;
            console.log('s = ' + s)
            sumNum += parseInt(s, 16);
            console.log('sumNum = ' + sumNum)
        }
        var cusChecksum = getComplementFormDEC(sumNum);
        // 返回值：十六进制数。
        function getComplementFormDEC(num) {
            // 转成二进制数
            var binStr = num.toString(2)
            console.log('binStr = ' + binStr)
            // 不足8位字符则补零
            var dvalue = 8 - binStr.length
            if (dvalue > 0) {
                for (var index = 0; index < dvalue; index++) {
                    binStr = '0' + binStr
                }
            }
            // 取二进制数的反码
            var resBin = ''
            for (var index = 0; index < binStr.length; index++) {
                const element = binStr[index];
                if (element === '0') {
                    resBin += '1'
                } else {
                    resBin += '0'
                }
            }
            console.log('res = ' + resBin)
            // 得到num的补码，以十进制数返回
            var resNum = parseInt(resBin, 2) + 1
            console.log('resNum = ' + resNum)

            // 返回十六进制数
            var resHex = resNum.toString(16).toUpperCase()
            console.log('resHex = ' + resHex)
            if (resHex.length > 2) {
                return resHex.substring(resHex.length - 2, resHex.length)
            }
            return resHex
        }

        return cusChecksum

    }

}
/**
 * 获取校验和
 * @param str 16进制字符串
 * 
 * @return 10进制检验和
 */
export const getCheckSum = str => {
    let len = str.length;
    let num = 0;
    for (let i = 0; i < len; i += 2) {
        let s = `0x${str.slice(i, i+2)}`;
        num += parseInt(s, 16);
    }

    return (num % 256).toString(16);
}

export function praseResponseData(resData) {
    // 解析返回的数据
    try {
        return JSON.parse(resData);
    } catch (error) {
        var dataStr = resData.replace(/:"{/g, ":{");
        dataStr = dataStr.replace(/}",/g, "},");
        dataStr = dataStr.replace(/}"}/g, "}}");
        dataStr = dataStr.replace(/\\/g, "");
        return JSON.parse(dataStr);
    }
};

/**
 * 校验和
 * 
 */
export const getChecksumWithStr = str => {
    let sumNum = 0;
    // 求十进制的和
    for (let i = 4; i < str.length; i += 2) {
        let s = `0x${str[i]}${str[i + 1]}`;
        // console.log('s = ' + s)
        sumNum += parseInt(s, 16);
        // console.log('sumNum = ' + sumNum)
    }
    var cusChecksum = getComplementFormDEC(sumNum);
    // 返回值：十六进制数。
    function getComplementFormDEC(num) {
        // 转成二进制数
        var binStr = num.toString(2)
        // console.log('binStr = ' + binStr)
        // 不足8位字符则补零
        var dvalue = 8 - binStr.length
        if (dvalue > 0) {
            for (var index = 0; index < dvalue; index++) {
                binStr = '0' + binStr
            }
        }
        // 取二进制数的反码
        var resBin = ''
        for (var index = 0; index < binStr.length; index++) {
            const element = binStr[index];
            if (element === '0') {
                resBin += '1'
            } else {
                resBin += '0'
            }
        }
        // console.log('res = ' + resBin)
        // 得到num的补码，以十进制数返回
        var resNum = parseInt(resBin, 2) + 1
        // console.log('resNum = ' + resNum)

        // 返回十六进制数
        var resHex = resNum.toString(16).toUpperCase()
        // console.log('resHex = ' + resHex)
        if (resHex.length > 2) {
            return resHex.substring(resHex.length - 2, resHex.length)
        }
        return resHex
    }

    return cusChecksum

}

export const getCheckSumVal = str => {   
    let qq = 0
    let len =  str.length
    for (let i = 4; i < len; i += 2) {
        let s = `0x${str.slice(i, i+2)}`;
        qq += parseInt(s, 16);
    }
    let oo = ~qq + 1
    return oo.toString(16)

}